// This File is part of the "nyaqt" Project
// 
// Copyright  2009 sometmes@gmail.com
// All rights reserved
// 
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Data.Common;
using nyaqt.Plugins;
using System.Text.RegularExpressions;
using System.IO;

namespace nyaqt.Plugins
{
    public partial class SimpleConnectionEditorType2 : UserControl, ISimpleConnectionEdit
    {
        protected DbProviderFactory _factory;
        protected IConnectionInfo _connectionInfo;
        protected nyaqt.Plugins.NyaqtConnectionStringBuilder _connectionStringBuilder;
        protected List<nyaqt.Plugins.NyaqtConnectionStringBuilder> _recent;
        protected object _browseServersItem = "<find servers>";
        protected object _retrieveDbs = "<connect>";
        protected bool _initialized = false;

        public SimpleConnectionEditorType2()
        {
            InitializeComponent();
        }

        protected ComboBox ServerBox;

        private void BindControls()
        {
            ServerBox.Text = _connectionStringBuilder.Server;
            DatabaseBox.Text = _connectionStringBuilder.Database;
            LoginBox.Text = _connectionStringBuilder.Login;
            PwdBox.Text = _connectionInfo.Password;
            windowsAuthCheckbox.Checked = "True".Equals(_connectionStringBuilder["Integrated Security"] as string, StringComparison.OrdinalIgnoreCase);
            WindowsAuthCheckbox_Dependencies();
        }

        public virtual void EditConnection(DbProviderFactory factory, IConnectionInfo cninfo, List<nyaqt.Plugins.NyaqtConnectionStringBuilder> recent)
        {
            _recent = recent;
            _factory = factory;
            _connectionInfo = cninfo as IConnectionInfo;
            _connectionStringBuilder = _connectionInfo.ConnectionStringBuilder.Copy();
            _connectionStringBuilder.ConnectionString = _connectionInfo.ConnectionStringWithPwd;

            EditConnection_PreBind();

            if (!_initialized)
            {
                List<string> servers = new List<string>();
                List<string> logins = new List<string>();
                List<string> dbs = new List<string>();

                bool useWinAuth = false;
                foreach (NyaqtConnectionStringBuilder bl in _recent)
                {
                    if (!string.IsNullOrEmpty(bl.Server) && !servers.Contains(bl.Server))
                        servers.Add(bl.Server);
                    if (!string.IsNullOrEmpty(bl.Login) && !logins.Contains(bl.Login))
                        logins.Add(bl.Login);
                    if (!string.IsNullOrEmpty(bl.Database) && !dbs.Contains(bl.Database))
                        dbs.Add(bl.Database);
                    if (bl["Integrated Security"] as string == "True")
                        useWinAuth = true;
                }

                ServerBox.Items.Clear();
                foreach (string item in servers)
                {
                    ServerBox.Items.Add(item);
                }
                ServerBox.Items.Add(_browseServersItem);

                LoginBox.Items.Clear();
                foreach (string item in logins)
                {
                    LoginBox.Items.Add(item);
                }
                windowsAuthCheckbox.Checked = useWinAuth;

                DatabaseBox.Items.Clear();
                foreach (string item in dbs)
                {
                    DatabaseBox.Items.Add(item);
                }
                DatabaseBox.Items.Add(_retrieveDbs);
                _initialized = true;
            }

            BindControls();
            SelectAliasFromServer();
        }

        protected virtual void EditConnection_PreBind()
        {
            
        }

        private void SimpleConnectionEditor_Load(object sender, EventArgs e)
        {
            ServerBox.Validated+=new EventHandler(Server_Validated);
            DatabaseBox.Validated += new EventHandler(Database_Validated);
            LoginBox.Validated += new EventHandler(Login_Validated);
            PwdBox.Validated += new EventHandler(Pwd_Validated);
       }

        void Pwd_Validated(object sender, EventArgs e)
        {
            _connectionInfo.Password = PwdBox.Text;
        }

        void Login_Validated(object sender, EventArgs e)
        {
            if (_connectionStringBuilder.Login != LoginBox.Text)
            {
                _connectionStringBuilder.Login = LoginBox.Text;
                _connectionInfo.ConnectionString = _connectionStringBuilder.ConnectionString;
                _connectionInfo.Password = _connectionStringBuilder.Password;
                CheckKnownPwd();
            }
        }

        void Database_Validated(object sender, EventArgs e)
        {
            if (_connectionStringBuilder.Database != DatabaseBox.Text)
            {
                _connectionStringBuilder.Database = DatabaseBox.Text;
                _connectionInfo.ConnectionString = _connectionStringBuilder.ConnectionString;
                _connectionInfo.Password = _connectionStringBuilder.Password;
                CheckKnownPwd();
            }
        }

        void CheckKnownPwd()
        {
            foreach (NyaqtConnectionStringBuilder bl in _recent)
            {
                if (ServerBox.Text.Equals(bl.Server,StringComparison.OrdinalIgnoreCase) 
                    &&
                    DatabaseBox.Text.Equals(bl.Database,StringComparison.OrdinalIgnoreCase)
                    && 
                    LoginBox.Text.Equals(bl.Login,StringComparison.OrdinalIgnoreCase))
                {
                    _connectionInfo.Password = bl.Password;
                    break;
                }
            }
        }

        private void Server_Validated(object sender, EventArgs e)
        {
            SelectAliasFromServer();
            RetrieveServerBox();
        }

        private void windowsAuthCheckbox_CheckedChanged(object sender, EventArgs e)
        {
            if (!windowsAuthCheckbox.Checked.ToString().Equals((_connectionStringBuilder["Integrated Security"] as string), StringComparison.OrdinalIgnoreCase))
            {
                _connectionStringBuilder["Integrated Security"] = windowsAuthCheckbox.Checked.ToString();
                _connectionInfo.ConnectionString = _connectionStringBuilder.ConnectionString;
                _connectionInfo.Password = _connectionStringBuilder.Password;
            }
            WindowsAuthCheckbox_Dependencies();
        }

        private void WindowsAuthCheckbox_Dependencies()
        {

            if (windowsAuthCheckbox.Checked)
            {
                LoginBox.Text = Environment.UserDomainName + "\\" + Environment.UserName;
                LoginBox.Enabled = false;
                PwdBox.Enabled = false;
            }
            else
            {
                LoginBox.Text = _connectionStringBuilder.Login;
                LoginBox.Enabled = true;
                PwdBox.Enabled = true;
            }
        }

        private void SelectAliasFromServer()
        {
            string addr = ServerBox.Text;
            IConnectionProperties cn = _connectionInfo.ConnectionProperties;
            AliasBox.Text = "";
            AliasBox.SelectedItem = null;
            foreach (ServerInfo item in AliasBox.Items)
            {
                if (cn.ServerAddressEqual(item.ServerAddress, addr))
                {
                    AliasBox.SelectedItem = item;
                }
            }
        }

        private void AliasBox_SelectionChangeCommitted(object sender, EventArgs e)
        {
            ServerInfo item = AliasBox.SelectedItem as ServerInfo;
            ServerBox.Text = item.ServerAddress;
            RetrieveServerBox();
        }

        private void AliasBox_Validated(object sender, EventArgs e)
        {
            int i = AliasBox.FindStringExact(AliasBox.Text);
            if (i != ListBox.NoMatches)
            {
                AliasBox.SelectedItem = AliasBox.Items[i];
                AliasBox_SelectionChangeCommitted(null, null);
            }
        }

        private void RetrieveServerBox()
        {
            if (_connectionStringBuilder.Server != ServerBox.Text)
            {
                _connectionStringBuilder.Server = ServerBox.Text;
                _connectionInfo.ConnectionString = _connectionStringBuilder.ConnectionString;
                _connectionInfo.Password = _connectionStringBuilder.Password;
                CheckKnownPwd();
            }
        }

        private void DatabaseBox_DropDown(object sender, EventArgs e)
        {
            //if (DatabaseBox.Items.Count > 0 && DatabaseBox.Items[0] == (object)_notloaded)
            //{
            //    if (_connectionInfo.ConnectionProperties.Connection == null)
            //    {
            //        string cns = _connectionInfo.ConnectionProperties.ChangeDatabase("master");

            //        IDbConnection cn = _connectionInfo.CreateConnection();
            //        cn.ConnectionString = cns;
            //        cn.Open();
            //        _connectionInfo.ConnectionProperties.Connection = cn;
            //    }
            //    List<DatabaseEntityInfo> dbs = _connectionInfo.ConnectionProperties.GetDatabases();
            //    DatabaseBox.Items.Clear();
            //    foreach (DatabaseEntityInfo db in dbs)
            //    {
            //        DatabaseBox.Items.Add(db.DatabaseName);
            //    }
            //}
        }

        private void ServerBox2_DropDownClosed(object sender, EventArgs e)
        {
            if (ServerBox.SelectedItem == _browseServersItem)
            {
                LoadBrowseServerList();
                ServerBox.DroppedDown = true;
                return;
            }

        }

        private void ServerBox_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (ServerBox.SelectedItem == null || ServerBox.SelectedItem == _browseServersItem) return;
            
            ServerBox.Text = ServerBox.SelectedItem.ToString();
            RetrieveServerBox();
        }

        private void LoadBrowseServerList()
        {
            List<ServerInfo> list = _connectionInfo.ConnectionProperties.GetServerList();
            ServerBox.Items.Clear();
            foreach (ServerInfo server in list)
            {
                ServerBox.Items.Add(server.DisplayName);
            }
        }

        private void LoadDatabaseList()
        {
            string dbname = _connectionInfo.ConnectionStringBuilder.Database;
            _connectionInfo.ConnectionStringBuilder.Database = "master";
            _connectionInfo.ConnectionString = _connectionInfo.ConnectionStringBuilder.ConnectionString;

            IDbConnection cn = _connectionInfo.CreateConnection();
            _connectionInfo.ConnectionStringBuilder.Database = dbname;
            _connectionInfo.ConnectionString = _connectionInfo.ConnectionStringBuilder.ConnectionString;

            cn.Open();
            _connectionInfo.ConnectionProperties.Connection = cn;
            List<DatabaseEntityInfo> list = _connectionInfo.ConnectionProperties.GetDatabases();
            DatabaseBox.Items.Clear();
            foreach (DatabaseEntityInfo db in list)
            {
                DatabaseBox.Items.Add(db.DisplayName);
            }
        }

        private void LoginBox_SelectionChangeCommitted(object sender, EventArgs e)
        {
            LoginBox.Text = LoginBox.SelectedItem.ToString();
            Login_Validated(sender, e);
        }

        private void DatabaseBox_DropDownClosed(object sender, EventArgs e)
        {
            if (DatabaseBox.SelectedItem == _retrieveDbs)
            {
                LoadDatabaseList();
                DatabaseBox.DroppedDown = true;
                return;
            }
        }

        private void DatabaseBox_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (DatabaseBox.SelectedItem == null || DatabaseBox.SelectedItem == _retrieveDbs) return;

            DatabaseBox.Text = DatabaseBox.SelectedItem.ToString();
            Database_Validated(sender, e);
        }

        private void AliasBox_DropDown(object sender, EventArgs e)
        {

        }

    }
}
































